"""
DingTalk API Client
Handles communication with DingTalk's API for sending messages
"""
import requests
import json
import time
import hmac
import hashlib
import base64
import urllib.parse
from typing import Dict, Any


class DingTalkClient:
    """
    A client for interacting with DingTalk API
    """
    def __init__(self, webhook_url: str = None, secret: str = None):
        """
        Initialize the client with webhook URL and optional secret for signing
        """
        self.webhook_url = webhook_url
        self.secret = secret

    def _get_signed_url(self, url: str, secret: str) -> str:
        """
        Generate a signed URL if a secret is provided
        """
        if not secret:
            return url
            
        timestamp = str(round(time.time() * 1000))
        secret_enc = secret.encode('utf-8')
        string_to_sign = '{}\n{}'.format(timestamp, secret)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        
        return f"{url}&timestamp={timestamp}&sign={sign}"

    def send_message(self, message_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        Send a message to DingTalk
        """
        if not self.webhook_url:
            return {"error": "Webhook URL is required"}

        # If there's a secret, generate a signed URL
        url = self._get_signed_url(self.webhook_url, self.secret)

        headers = {
            'Content-Type': 'application/json'
        }

        try:
            response = requests.post(
                url,
                headers=headers,
                data=json.dumps(message_data),
                timeout=10
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            return {"error": f"Request failed: {str(e)}"}
        except Exception as e:
            return {"error": f"An error occurred: {str(e)}"}


# Example usage function
def send_card_to_dingtalk(card_data: Dict[str, Any], webhook_url: str, secret: str = None) -> Dict[str, Any]:
    """
    Convenience function to send a card to DingTalk
    """
    client = DingTalkClient(webhook_url, secret)
    return client.send_message(card_data)